Skip to content

Conversation

@trangdoan982
Copy link
Collaborator

@trangdoan982 trangdoan982 commented Nov 19, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new color picker component for selecting relationship type colors, featuring dropdown selection and visual color swatches.
  • Improvements

    • Enhanced color consistency across relationship type rendering with improved validation, fallback handling, and contrast-aware color display.

@linear
Copy link

linear bot commented Nov 19, 2025

@supabase
Copy link

supabase bot commented Nov 19, 2025

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@trangdoan982
Copy link
Collaborator Author

@coderabbitai full review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 19, 2025

📝 Walkthrough

Walkthrough

This PR introduces a centralized color management system for relation types, replacing hardcoded hex colors with semantic color names. It adds a ColorPicker UI component, defines Tldraw color constants and types, updates the DiscourseRelationType schema, and propagates color values through arrow creation and canvas rendering with fallback defaults.

Changes

Cohort / File(s) Summary
Color System Infrastructure
apps/obsidian/src/utils/tldrawColors.ts (new)
Defines TLDRAW_COLOR_NAMES array, TldrawColorName type, TLDRAW_COLOR_LABELS mapping, DEFAULT_TLDRAW_COLOR constant, and COLOR_PALETTE hex mapping for centralized color management.
apps/obsidian/src/types.ts
apps/obsidian/src/constants.ts
Settings & UI
apps/obsidian/src/components/RelationshipTypeSettings.tsx
Introduces ColorPicker component with internal state and dropdown for predefined colors; replaces native color input; wires color updates to use TldrawColorName; defaults new relation types to DEFAULT_TLDRAW_COLOR.
Canvas Integration
apps/obsidian/src/components/canvas/DiscourseRelationTool.ts
Sets color field on DiscourseRelationShape during arrow creation, using relationType?.color with DEFAULT_TLDRAW_COLOR fallback.
apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx
apps/obsidian/src/components/canvas/utils/relationUtils.tsx

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant RelationshipTypeSettings
    participant ColorPicker
    participant Canvas
    participant relationUtils

    User->>RelationshipTypeSettings: Edit relation type
    RelationshipTypeSettings->>ColorPicker: Render with current color
    User->>ColorPicker: Select color from palette
    ColorPicker->>RelationshipTypeSettings: onChange(TldrawColorName)
    RelationshipTypeSettings->>RelationshipTypeSettings: Update state (color as TldrawColorName)
    RelationshipTypeSettings->>Canvas: Save relation type config
    
    Canvas->>DiscourseRelationTool: Create arrow for relation
    DiscourseRelationTool->>Canvas: Set shape color (relationType?.color ?? DEFAULT_TLDRAW_COLOR)
    
    Canvas->>relationUtils: Render arrow shape
    relationUtils->>relationUtils: Validate color against theme
    relationUtils->>relationUtils: Resolve colorHex (theme lookup or DEFAULT_TLDRAW_COLOR)
    relationUtils->>Canvas: Render with resolved colorHex (stroke & fill)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Extra attention areas:
    • ColorPicker component in RelationshipTypeSettings: Verify click-outside handling, dropdown state management, and integration with form submission flow
    • Color validation logic in relationUtils.tsx: Ensure theme-aware color resolution handles edge cases (invalid color names, missing theme)
    • Type consistency: Confirm all color field assignments use TldrawColorName (e.g., DEFAULT_RELATION_TYPES, arrow creation, shape updates)
    • Breaking change: Verify DiscourseRelationType.color type change from string to TldrawColorName doesn't break existing stored data or migrations

Possibly related PRs

Pre-merge checks

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly reflects the main change: constraining relation colors to match the Tldraw palette with semantic names instead of arbitrary hex values.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
apps/obsidian/src/components/canvas/utils/relationUtils.tsx (1)

1889-1892: Consider including color in changeIndex memo dependencies.

The changeIndex memo currently depends only on shape, which should capture color changes since color is a shape property. However, consider explicitly including color-related values in the dependency array for clarity and to ensure Safari-specific re-rendering works correctly when colors change.

Consider this for explicitness:

  const changeIndex = React.useMemo<number>(() => {
    return editor.environment.isSafari ? (globalRenderIndex += 1) : 0;
-  }, [shape]);
+  }, [shape, colorName]);

Though the current implementation should work since shape changes when its color changes.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18e7685 and e0e16ac.

📒 Files selected for processing (7)
  • apps/obsidian/src/components/RelationshipTypeSettings.tsx (6 hunks)
  • apps/obsidian/src/components/canvas/DiscourseRelationTool.ts (2 hunks)
  • apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx (2 hunks)
  • apps/obsidian/src/components/canvas/utils/relationUtils.tsx (5 hunks)
  • apps/obsidian/src/constants.ts (1 hunks)
  • apps/obsidian/src/types.ts (2 hunks)
  • apps/obsidian/src/utils/tldrawColors.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-06-17T23:42:29.279Z
Learnt from: maparent
Repo: DiscourseGraphs/discourse-graph PR: 220
File: apps/roam/src/utils/conceptConversion.ts:95-104
Timestamp: 2025-06-17T23:42:29.279Z
Learning: In the DiscourseGraphs/discourse-graph codebase, DiscourseRelation type properties are either string or Triple[], and the STANDARD_ROLES filter in conceptConversion.ts excludes Triple[] properties, so only string values remain after filtering.

Applied to files:

  • apps/obsidian/src/types.ts
  • apps/obsidian/src/components/canvas/DiscourseRelationTool.ts
  • apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx
📚 Learning: 2025-06-17T23:37:45.289Z
Learnt from: maparent
Repo: DiscourseGraphs/discourse-graph PR: 220
File: apps/roam/src/utils/conceptConversion.ts:42-56
Timestamp: 2025-06-17T23:37:45.289Z
Learning: In the DiscourseNode interface from apps/roam/src/utils/getDiscourseNodes.ts, the field `node.type` serves as the UID field rather than having a conventional `node.uid` field. This is an unusual naming convention where the type field actually contains the unique identifier.

Applied to files:

  • apps/obsidian/src/types.ts
📚 Learning: 2025-06-17T23:37:45.289Z
Learnt from: maparent
Repo: DiscourseGraphs/discourse-graph PR: 220
File: apps/roam/src/utils/conceptConversion.ts:42-56
Timestamp: 2025-06-17T23:37:45.289Z
Learning: In the DiscourseNode interface from apps/roam/src/utils/getDiscourseNodes.ts, the field `type` serves as the unique identifier field, not a type classification field. The interface has no `uid` or `id` field, making `node.type` the correct field to use for UID-related operations.

Applied to files:

  • apps/obsidian/src/types.ts
📚 Learning: 2025-06-22T10:40:52.752Z
Learnt from: sid597
Repo: DiscourseGraphs/discourse-graph PR: 232
File: apps/roam/src/utils/getAllDiscourseNodesSince.ts:18-31
Timestamp: 2025-06-22T10:40:52.752Z
Learning: In apps/roam/src/utils/getAllDiscourseNodesSince.ts, the user confirmed that querying for `?title` with `:node/title` and mapping it to the `text` field in the DiscourseGraphContent type is the correct implementation for retrieving discourse node content from Roam Research, despite it appearing to query page titles rather than block text content.

Applied to files:

  • apps/obsidian/src/types.ts
🔇 Additional comments (11)
apps/obsidian/src/components/canvas/DiscourseRelationTool.ts (1)

254-254: LGTM! Clean fallback pattern for relation color.

The color assignment correctly uses the relation type's color when available, falling back to DEFAULT_TLDRAW_COLOR otherwise. This ensures every relation shape has a valid color from the Tldraw palette.

apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx (1)

381-381: LGTM! Consistent color fallback pattern.

The color assignment mirrors the approach in DiscourseRelationTool.ts, ensuring consistency across different relation creation paths.

apps/obsidian/src/utils/tldrawColors.ts (2)

1-60: Well-structured color management system.

The centralized color utilities provide:

  • Type-safe color name constraints via TldrawColorName
  • Human-readable labels for UI display
  • A default fallback color
  • Hex value mappings for rendering

This design enables consistent color handling across the application.


46-60: No issues found – the COLOR_PALETTE hex values appear correct.

The palette in apps/obsidian/src/utils/tldrawColors.ts is identical to the verified COLOR_PALETTE in apps/roam/src/components/canvas/DiscourseNodeUtil.tsx, which is explicitly sourced from @tldraw/editor/editor.css. Both files maintain consistent color definitions across the codebase, and the values are properly mapped to tldraw's standard color names.

apps/obsidian/src/components/canvas/utils/relationUtils.tsx (1)

1882-1887: Good color validation with theme fallback.

The color validation logic ensures that shape.props.color is a valid key in the theme. If invalid, it falls back to DEFAULT_TLDRAW_COLOR. This prevents runtime errors when rendering shapes with invalid color values.

apps/obsidian/src/components/RelationshipTypeSettings.tsx (4)

21-109: Well-implemented ColorPicker component with accessibility considerations.

The custom ColorPicker provides:

  • Click-outside closing behavior via refs and event listeners
  • Proper cleanup in useEffect return
  • Contrast-aware text coloring for accessibility
  • Visual color swatches for easy identification
  • Integration with TldrawColorName type system

The implementation is clean and follows React best practices.


133-137: Good type-safe handling of color field updates.

The conditional logic properly narrows the type for color updates, ensuring type safety when assigning TldrawColorName values. This prevents type errors while maintaining flexibility for other string fields.


193-198: Color validation added to save logic.

The validation now checks that the color field is populated, treating it as a required field alongside id, label, and complement. This ensures data integrity.


14-14: No issues found—the utility is correctly implemented and imported.

The getContrastColor function exists at apps/obsidian/src/utils/colorUtils.ts and is properly exported. The import in RelationshipTypeSettings.tsx line 14 is valid and the function is actively used in the component for text color accessibility calculations. No action required.

apps/obsidian/src/constants.ts (1)

31-44: Color mappings verified—changes are correct.

All semantic color names map to the exact hex values that were previously hardcoded:

  • "green"#099268
  • "red"#e03131
  • "grey"#adb5bd

The refactoring from hex strings to semantic color names preserves visual appearance and aligns correctly with the Tldraw palette defined in COLOR_PALETTE.

apps/obsidian/src/types.ts (1)

2-2: Add type validation and document color compatibility.

The type change from string to TldrawColorName improves type safety, and all default values are already compatible semantic colors. However, the change lacks runtime validation when loading settings.

Key findings:

  • DEFAULT_RELATION_TYPES already use valid TldrawColorName values ("green", "red", "grey")
  • Settings load with Object.assign using unsafe as TldrawColorName cast (no validation)
  • RelationshipTypeSettings allows custom relation type creation, all constrained to semantic colors
  • No migration logic or validation guards

The practical risk is low since:

  1. Default values are compatible
  2. UI constrains colors to semantic names only
  3. No evidence users created non-semantic color values

However, recommend adding a validation step in loadSettings() to ensure color values match TldrawColorName and log/fall back to defaults for invalid values. This prevents silent failures if old data exists.

@trangdoan982
Copy link
Collaborator Author

next action: waiting for review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

No open projects
Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants